//
//  Node.m
//  RoutingEvaluator
//
//  Created by Christopher Kemsley on 4/12/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#import "NodeInfo.hpp"
#import <Foundation/Foundation.h>

NamespaceBegin


NodeInfo*	NodeInfo :: createNode	( Identifier const & inID , Vector2D const & inPoint )
	{
	return new NodeInfo ( inID , inPoint ) ;
	}

NodeInfo :: NodeInfo ( Identifier const & inID , Vector2D const & inPoint )
:	identifier(inID)
,	location(inPoint)
	{
	
	}

Float64		NodeInfo :: distanceFromNode	( NodeInfo const * info ) const
	{
	Vector2D	v	( location ) ;
	v	-=	info->location ;
	return v.norm2() ;
	}




NodeInfoSet*		NodeInfoSet :: createDefaultNodeSet ()
	{
	std::vector<NodeInfo*>	n ;
	n.reserve(12) ;
	
	Vector2D s (33.69,49.97) ;
	
	n . push_back ( new NodeInfo ( 1  , Vector2D(	33.69	,	49.97	) ) ) ;
	n . push_back ( new NodeInfo ( 2  , Vector2D(	48.08	,	2.94	) ) ) ;
	n . push_back ( new NodeInfo ( 3  , Vector2D(	18.01	,	27.42	) ) ) ;
	n . push_back ( new NodeInfo ( 4  , Vector2D(	13.08	,	29.86	) ) ) ;
	n . push_back ( new NodeInfo ( 5  , Vector2D(	2.46	,	28.55	) ) ) ;
	n . push_back ( new NodeInfo ( 6  , Vector2D(	35.04	,	48.11	) ) ) ;
	n . push_back ( new NodeInfo ( 7  , Vector2D(	37.52	,	36.99	) ) ) ;
	n . push_back ( new NodeInfo ( 8  , Vector2D(	21.59	,	31.71	) ) ) ;
	n . push_back ( new NodeInfo ( 9  , Vector2D(	40.15	,	4.19	) ) ) ;
	n . push_back ( new NodeInfo ( 10 , Vector2D(	47.27	,	45.79	) ) ) ;
	n . push_back ( new NodeInfo ( 11 , Vector2D(	30.0	,	12.67	) ) ) ;
	n . push_back ( new NodeInfo ( 12 , Vector2D(	43.67	,	25.67	) ) ) ;
	
	return new NodeInfoSet ( n ) ;
	}
NodeInfoSet*		NodeInfoSet :: createWithContentsOfFile ( std::string const & cpath )
	{
	NSError*	error	=	0 ;
	
	NSString	*	path	=	[NSString stringWithCString:cpath.c_str() encoding:NSASCIIStringEncoding] ;
	
	NSString	*	raw		=	[NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:&error] ;
	
	if ( error )
		{
		ThrowException ( "NodeInfoSet" , "Failed reading node info from \""<<cpath<<"\": "<<[[error description] cStringUsingEncoding:NSASCIIStringEncoding] , __FILE__,__LINE__ ) ;
		}
	
	std::vector<NodeInfo*>	n ;
	
	Identifier i = 1 ;
	
	
	/* Setup the scanner */
	
	NSCharacterSet * numberSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890.-"] ;
	
	NSScanner	*	scanner	=	[NSScanner scannerWithString:raw] ;
	
	[scanner setCharactersToBeSkipped:[numberSet invertedSet]] ;
	
	
	double x ;
	while ( [scanner scanDouble:&x] )
		{
		double y ;
		if ( [scanner scanDouble:&y] )
			{
			n . push_back ( new NodeInfo ( i++  , Vector2D(	x,y	) ) ) ;
			}
		}
	
	if ( n.size() < 2 )
		{
		ThrowException ( "NodeInfoSet" , "Failed reading node info from \""<<cpath<<"\": fewer than two nodes were detected" , __FILE__,__LINE__ ) ;
		}
	
	return new NodeInfoSet ( n ) ;
	}




std::vector<NodeInfo*> const&	NodeInfoSet :: nodes ()
	{
	return mNodes ;
	}


NodeInfoSet :: NodeInfoSet ( std::vector<NodeInfo*> const & infos )
:	mNodes(infos)
	{
	
	}
NodeInfo*	NodeInfoSet :: nodeWithIdentifier	( Identifier const & identifier )
	{
	std::vector<NodeInfo*>::iterator	here	=	mNodes.begin() ;
	std::vector<NodeInfo*>::iterator	end		=	mNodes.end() ;
	while ( here < end )
		{
		NodeInfo * n = *(here++) ;
		if ( (n->identifier) == identifier )
			return n ;
		}
	return 0 ;
	}


NamespaceEnd
